#ifndef U2ConfigFile_H
#define U2ConfigFile_H

#include "U2PreRequest.h"
#include "U2MemoryAllocatorConfig.h"
#include "U2SharedPtr.h"
#include "U2DataStreamFileStream.h"
#include "U2StringUtil.h"
#include "U2IteratorWrappers.h"


U2EG_NAMESPACE_BEGIN


/** Class for quickly loading settings from a text file.
    @remarks
        This class is designed to quickly parse a simple file containing
        key/value pairs, mainly for use in configuration settings.
    @par
        This is a very simplified approach, no multiple values per key
        are allowed, no grouping or context is being kept etc.
    @par
        By default the key/values pairs are tokenised based on a
        separator of Tab, the colon (:) or equals (=) character. Each
        key - value pair must end in a carriage return.
    @par
        Settings can be optionally grouped in sections, using a header
        beforehand of the form [SectionName]. 
*/
class _U2Share U2ConfigFile : public ConfigAlloc
{
public:
    U2ConfigFile(void);
    virtual ~U2ConfigFile(void);

    /// load from a filename (not using resource group locations)
    void load(const U2String& filename, const U2String& separators = "\t:=", bool trimWhitespace = true);
    /// load from a filename (using resource group locations)
    void load(const U2String& filename, const U2String& resourceGroup, const U2String& separators = "\t:=", bool trimWhitespace = true);
    /// load from a data stream
    void load(const U2DataStreamPtr& stream, const U2String& separators = "\t:=", bool trimWhitespace = true);
	/// load from a filename (not using resource group locations)
	void loadDirect(const U2String& filename, const U2String& separators = "\t:=", bool trimWhitespace = true);
	/// load from a filename (using resource group locations)
	void loadFromResourceSystem(const U2String& filename, const U2String& resourceGroup, const U2String& separators = "\t:=", bool trimWhitespace = true);

    /** Gets the first setting from the file with the named key. 
    @param key The name of the setting
    @param section The name of the section it must be in (if any)
	@param defaultValue The value to return if the setting is not found
    */
    U2String getSetting(const U2String& key, const U2String& section = U2StringUtil::BLANK, const U2String& defaultValue = U2StringUtil::BLANK) const;
    /** Gets all settings from the file with the named key. */
    U2StringVector getMultiSetting(const U2String& key, const U2String& section = U2StringUtil::BLANK) const;


    typedef std::multimap<U2String, U2String>           SettingsMultiMap;
    typedef MapIterator<SettingsMultiMap>               SettingsIterator;
    /** Gets an iterator for stepping through all the keys / values in the file. */
    typedef std::map<U2String, SettingsMultiMap*>       SettingsBySection;
    typedef MapIterator<SettingsBySection>              SectionIterator;

    /** Get an iterator over all the available sections in the config file */
    SectionIterator getSectionIterator(void);
    /** Get an iterator over all the available settings in a section */
    SettingsIterator getSettingsIterator(const U2String& section = U2StringUtil::BLANK);

    /** Clear the settings */
    void clear(void);

protected:
    SettingsBySection mSettings;
};


U2EG_NAMESPACE_END

#endif